from flask import g
from flask import request
from flask import session

from info import db
from info.models import Category, News
from . import profile_blue
from info.utils.commons import login_required
from flask import render_template, jsonify, redirect, current_app
from info.utils.response_code import RET
# 导入七牛云
from info.utils.image_storage import storage
# 导入常量文件(七牛云空间域名)
from info.constants import QINIU_DOMIN_PREFIX


@profile_blue.route('/info')
@login_required
def user_info():
    """个人中心"""
    '''
    个人中心首页
    1、判断是否登录
    2、返回用户信息给模板
    '''
    # 通过登录验证装饰器获取用户信息
    user = g.user
    # 判断是否登录(如果未登录，返回主界面)
    if not user:
        return redirect('/')
    # 如果已登录，返回用户信息
    data = {
        'user_info': user.to_dict()
    }
    return render_template('news/user.html', data=data)


@profile_blue.route('/base_info', methods=['GET', 'POST'])
@login_required
def base_info():
    '''
    用户基本信息展示和修改
    基本信息有两种请求，点击时为get请求，获取信息
    点击保存时为post请求，存储信息
    1、通过登录验证装饰器获取用户信息
    2、判断请求方式
        GET请求将用户信息返回页面
        POST请求
        1、获取参数
        2、验证参数完整性
        3、检查性别参数(MAN、WOMAN)
        4、存储用户信息
        5、缓存用户信息
        6、返回数据给模板
    :return:
    '''
    # 通过登录验证装饰器获取用户信息
    user = g.user
    # 判断请求方式
    # GET请求
    if request.method == 'GET':
        print('get')
        # 返回的数据
        data = {
            'user_info': user
        }
        # 返回数据给模板
        return render_template('news/user_base_info.html', data=data)
    # POST请求
    # 获取参数
    print('post')
    signature = request.json.get('signature')
    nick_name = request.json.get('nick_name')
    gender = request.json.get('gender')
    # 验证参数完整性
    if not all({signature, nick_name, gender}):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    # 验证性别参数
    if gender not in ['MAN', 'WOMAN']:
        return jsonify(errno=RET.PARAMERR, errmsg='性别格式错误')
    # 存储用户信息
    user.signature = signature
    user.nick_name = nick_name
    user.gender = gender
    # 提交
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='存储基本信息失败')
    print(user.nick_name)
    # 修改缓存数据
    session['nick_name'] = nick_name
    # 返回结果(此时模板经过GET请求已经加载，不用返回数据，只用返回结果就行)
    return jsonify(errno=RET.OK, errmsg='OK')


@profile_blue.route('/pic_info', methods=['GET', 'POST'])
@login_required
def pic_info():
    '''
    头像修改
    1、通过登录验证装饰器获取用户信息
    2、判断请求方式
    3、获取参数avatar(头像)
    4、验证参数
    5、读取图片数据(转为二进制？)
    6、将图片上传到七牛云
    7、保存七牛云返回的图片名称
    8、将返回的图片名称(相对数据)储存数据库
    9、提交数据
    10、将七牛云外链域名+图片名称(绝对路径)返回前端
    没有缓存
    :return:
    '''
    # 获取用户信息
    user = g.user
    # 判断请求方式
    if request.method == 'GET':
        # 返回数据到模板
        data = {
            'user': user.to_dict()
        }
        return render_template('news/user_pic_info.html', data=data)
    # post请求
    # 获取参数
    avatar = request.files.get('avatar')
    # 验证参数
    if not avatar:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
    # 转化参数为bytes
    try:
        image_data = avatar.read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='图片格式错误')
    # 调用七牛云上传图片,获取图片名
    try:
        image_name = storage(image_data)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='上传头像失败(第三方异常)')
    # 存储数据
    user.avatar_url = image_name
    # 提交数据
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='保存头像失败')
    # 拼接绝对路径返回前端
    avatar_url = QINIU_DOMIN_PREFIX + image_name
    data = {
        'avatar_url': avatar_url
    }
    return jsonify(errno=RET.OK, errmsg='OK', data=data)


@profile_blue.route('/news_release', methods=['GET', 'POST'])
@login_required
def news_release():
    '''
    新闻发布
    1、根据登录装饰器获取
    2、判断请求
    3、get请求下
        1、查询新闻分类信息
        2、判断查询结果
        3、返回数据模板
    4、post请求下获取数据
        title(新闻标题),category_id(分类id),digest(新闻摘要),index_image(索引图片),content(新闻内容)
    5、检查参数完整性
    6、检查新闻分类类型(转化为整形)
    7、读取图片数据
    8、上传数据到七牛云，获取七牛云返回的图片名称
    9、保存数据
    10、提交数据
    11、返回结果
    :return:
    '''
    # 根据登录验证装饰器获取用户信息
    user = g.user
    # 判断请求方法
    if request.method == 'GET':
        # 从数据库中查询新闻分类
        try:
            category = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg='查询新闻分类失败')
        # 判断查询结果
        if not category:
            return jsonify(errno=RET.NODATA, errmsg='没有新闻分类信息')
        # 删除'最新'分类
        category.pop(0)
        # 返回数据给模板
        data = {
            'categories': category
        }
        return render_template('news/user_news_release.html', data=data)
    # post请求
    # 获取参数
    title = request.form.get('title')
    category_id = request.form.get('category_id')
    digest = request.form.get('digest')
    index_image = request.files.get('index_image')
    content = request.form.get('content')
    # 判断参数完整性
    if not all([title, category_id, digest, index_image, content]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    # 检查新闻分类(转为整形)
    try:
        category_id = int(category_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='参数类型错误')
    # 读取图片数据
    try:
        image_data = index_image.read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='图片类型错误')
    # 上传图片到七牛云
    try:
        image_name = storage(image_data)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='上传图片失败')
    # 保存数据
    news = News()
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.index_image_url = QINIU_DOMIN_PREFIX + image_name  # 因为新闻显示是直接从数据库中取得，所以这里要先拼接路径
    news.content = content

    news.user_id = user.id
    news.source = '个人发布'
    # 新闻状态
    news.status = 1
    # 提交数据
    try:
        db.session.add(news)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.tollback()
        return jsonify(errno=RET.DBERR, errmsg='存储用户信息失败')
    # 返回结果
    return jsonify(errno=RET.OK, errmsg='OK')
